
import * as Cesium from 'cesium'
import DrawTool from './DrawTool'


class VisibilityAnalysis {
  constructor(viewer, tile) {
    this.viewer = viewer
    this.tile = tile
    this.resultLines =[]
    this.points =[]
    this.drawTool = null
  }

  Types = {
    singlelineAnalysis: 'singlelineAnalysis',
    rangeAnalysis: 'rangeAnalysis'
  }

  // 激活工具，传入DrawType
  active(drawType) {
    // 如果在我们的绘制工具集合中，存在这个工具
    if (Object.keys(this.Types).includes(drawType)) {
      this.drawTool = new DrawTool(this.viewer)
      this.endAnaysis()
      console.log(this.drawTool,'drawTool');
      this.listener()
      this.drawType = drawType
      if (drawType == this.Types.singlelineAnalysis) {
        this.drawTool.active(this.drawTool.DrawTypes.Polyline)
      } else if (drawType == this.Types.rangeAnalysis) {
        this.drawTool.active(this.drawTool.DrawTypes.Circle)
      }
    } else {
      return
    }
  }
  listener() {
    // 监听绘制结束事件
    this.drawTool.DrawEndEvent.addEventListener((drawEnt, positions, drawType, circlePoints) => {
      // console.log(drawEnt)
      // console.log(positions)
      // console.log(drawType)
      // console.log(circlePoints)
      // 为了避免编辑于绘制冲突，先移除绘制的元素
      this.drawTool.removeAllDrawEnts()
      if (positions?.length !== 2) {
        return
      }
      if (drawType === this.drawTool.DrawTypes.Polyline) {
        this.generatePoint('start', positions[0])
        this.generatePoint('end', positions[1])
        // 开始通视分析
        this.startAnysis(positions)
      } else if (drawType === this.drawTool.DrawTypes.Circle) {
        this.generatePoint('start', positions[0])
        this.startAnysisCricle(positions, circlePoints)
      }
    })
  }
  // 添加点
  generatePoint(type, position) {
    let text = type == 'start' ? '观察起点' : '观察终点'
    const point = this.viewer.entities.add({
      position: position,
      label: {
        text: text,
        fillColor: Cesium.Color.WHITE,
        scale: 0.5,
        font: 'normal 34px MicroSoft YaHei',
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
        scaleByDistance: new Cesium.NearFarScalar(500, 1, 1500, 0.4),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -20),
        outlineWidth: 3,
        outlineColor: Cesium.Color.BLACK
      },
      point: {
        color: Cesium.Color.BLUE,
        pixelSize: 5,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 2,
        scaleByDistance: new Cesium.NearFarScalar(1000, 1, 4200, 0.4),
        disableDepthTestDistance: 500
      }
    })
    this.points.push(point)
  }
   startAnysis(positions){
    // 计算射线的方向，目标点left 视域点right
    // normalize 归一化向量
    // subset 是坐标的减法，向量是终点-起点
    const direction = Cesium.Cartesian3.normalize(
      Cesium.Cartesian3.subtract(positions[1], positions[0], new Cesium.Cartesian3()),
      new Cesium.Cartesian3()
    )
    // 建立射线
    const ray = new Cesium.Ray(positions[0], direction)
    const result = this.viewer.scene.pickFromRay(ray, [this.tile]) // 计算交互点，返回第一个
    console.log(result, '第一个交互点')
    this.handleIntersection(result, positions[0], positions[1])
  }
   handleIntersection(result, startPosition, endPosition){
    // 如果是场景模型的交互点，排除交互点是地球表面
    if (Cesium.defined(result) && Cesium.defined(result.object)) {
      this.resultLines.push(this.drawLine([startPosition, result.position], Cesium.Color.GREEN))
      this.resultLines.push(this.drawLine([result.position, endPosition], Cesium.Color.RED))
    }
  }
   drawLine(positions, color){
    return this.viewer.entities.add({
      polyline: {
        positions: positions,
        width: 2,
        material: color,
        depthFailMaterial: color
      }
    })
  }
   startAnysisCricle(positions, circlePoints){
    // 圆边的坐标需要进行转换，在地形上找到一个特定点，并把它“夹紧”到地形的高度上。
    const clampPoints = circlePoints.map((circlePoint) => {
      return this.viewer.scene.clampToHeight(circlePoint)
    })
    clampPoints.forEach((clampPoint) => {
      // 计算射线的方向，目标点left 视域点right
      const direction = Cesium.Cartesian3.normalize(
        Cesium.Cartesian3.subtract(clampPoint, positions[0], new Cesium.Cartesian3()),
        new Cesium.Cartesian3()
      )
      // 建立射线
      const ray = new Cesium.Ray(positions[0], direction)
      const result = this.viewer.scene.pickFromRay(ray, [this.tile]) // 计算交互点，返回第一个
      this.handleIntersection(result, positions[0], clampPoint)
    })
  }
  
   endAnaysis(){
    this.resultLines.forEach((line) => {
      this.viewer.entities.remove(line)
    })
    this.resultLines = []
    this.points.forEach((point) => {
      this.viewer.entities.remove(point)
    })
    this.points = []
    this.drawTool.deactive()
  }
}

export default VisibilityAnalysis
